home *** CD-ROM | disk | FTP | other *** search
/ Cracking 2 / Cracking II..iso / Texty / crackme / SiFLyiNG_11.txt < prev    next >
Encoding:
Text File  |  1999-08-18  |  12.6 KB  |  315 lines

  1.  
  2.         SiFLyiNG
  3.                 Tutorial #11
  4.  
  5. ____________________________________________________________________________
  6.  
  7. Target          : webm4sta Crackme v1.0
  8.                   d/l it on http://crackmes.cjb.net
  9. Protection type : VB crackme, serial/name
  10. Level           : really don't know :)
  11. Tools needed    : Smatcheck for serial
  12.                   Smartcheck/SoftIce for Keygen
  13.                   A brain (optional for serial only)
  14.                   Some punk music, i.e. Bad Religion or NOFX today ;)
  15.  
  16. ____________________________________________________________________________
  17.  
  18. Before beginning...
  19.  
  20.         This crackme is coded in VB5. If you read the nfo, you'll see:
  21. "Rules: Takeout NAG Screen and hunt a serial # down *OR* make keygen." In
  22. this tut we'll see the last 2 parts (serial & keygen) only. The reason is that
  23. i was not able to takeout the nag, and i really wonder if it's possible,
  24. because the nag is the main form of the crackme and is called by ThunRTMain.
  25. I think i've told enough as introduction, so we must be ready to start...
  26.  
  27. ____________________________________________________________________________
  28.  
  29. The essay...
  30.  
  31. 1. The serial
  32.                                                   
  33.         First of all, i suppose you've correctly setup Smartcheck, because
  34. this is not the aim of the crackme. If it's not the case, just look for EB
  35. tutorial on Smartcheck.
  36.         So, let's fire up Smartcheck, open the VBCrcMe1.exe and select start.
  37. There you should see the nag, which says 'NAG - Unregistered'. Let's press
  38. the ok button, and a new form is shown, with two textbox, one for the name,
  39. the other for the Serial.
  40.         There type 'SiFLyiNG' in the first one, and '12345678' in the second
  41. one. Press the 'OK' button and what do you see :
  42.         "Error"
  43.         "Error: Invalid Serial"
  44.         "MuHAHA, Try Again"
  45.         It seems that '12345678' is not the valid serial here :)
  46.  
  47.         From there you return to Smartcheck.  Select -if it's not already
  48. done- 'Show errors and specific events' in the View program. This will limit
  49. the informations that appear in the main left window.
  50.         Just have a look at this window. We see:
  51.  
  52. Command1 (CommandButton) created
  53. Label1 (Label) created
  54. + Command1_Click
  55. + CmdOK(0)_Click
  56.  
  57.         OK, let's explain all these lines :
  58.  
  59. Command1 (CommandButton) created : the OK button of the nag has been created
  60. Label1 (Label) created : the label with the 'NAG' caption on the NAG has been
  61.                         created
  62.  
  63. + Command1_Click : here you have clicked on the button called Command1 which
  64.                 is actually the OK button of the NAG form.
  65.  
  66. NB : If you click on the + sign near the Command1_Click event in order to
  67.      expand the thread, you'll see what this action (called 'event' in VB
  68.      has made : Form1.Hide (hide the nag), CmdExit(1) (CommandButton) created,
  69.      CmdOK(0) (CommandButton) created, TextSerial (Textbox) created... and
  70.      finally Form2.Show which load the Registration Form.
  71.  
  72.      But this part is not interesting... let's have a look at the
  73. CmdOK(0)_Click. This will show us the CmdOK(0)_Click procedure. So click on
  74. + sign to open up the threads and you see that :
  75.  
  76. - CmdOK(0)_Click
  77.         TextName.Text
  78.         Val(String:"SiFLyiNG") returns double:0
  79.         Double(0) --> String("0")
  80.         TextSerial.Text
  81.         Val(String:"12345678") returns double: 1.23457e+007
  82.         Double(1.123457) --> String("12345678")
  83.         Len(String:"0") returns LONG:1
  84.         Str(VARIANT:Double:1.45236e+009)
  85.         String("1452356358") --> Double(1.45236e+009)
  86.         TextSerial.Text
  87.         String("12345678") --> Double(1.123457e+007)
  88.         Command1 (CommandButton) created
  89.         Label1 (Label) created
  90.         Form3.Show
  91.  
  92.         We have here all the necessary to find the serial :
  93.  
  94. String("1452356358") --> Double(1.45236e+009) : what's that ?
  95. TextSerial.Text
  96. String("12345678") --> Double(1.123457e+007) : the entered serial
  97.  
  98.         Hummm... i think it's clear. Type '1452356358' instead of our dummy
  99. serial, press the OK button and: "Great job"
  100.         OK, we find a serial. Now let's try to keygen it...
  101.  
  102. 2. The keygen
  103.  
  104.         2.a) Smartcheck
  105.  
  106.         What we found with Smartcheck is enough to find the valid serial, but
  107. not to keygen this crackme. Let's resume what we know just with Smartcheck :
  108.  
  109. Val(String:"SiFLyiNG") returns double:0
  110.  
  111.         Val function: returns the numbers contained in a string as a numeric
  112. value of appropriate type (here a double), i.e.:
  113.         Val("1234") returns 1234
  114.         Val("5 6 78") returns 5678
  115.         Val("Toto") returns 0
  116.         Val("123AZERTY") returns 123
  117.  
  118.         So you easily deduce that this function returns 0 when any name which
  119. doesn't begin with a number is entered. Moreover you'll see that the serial
  120. is the same for any name which doesn't begin with a number different from 0.
  121.  
  122.         Then you see that :
  123.  
  124. Double(0) --> String("0")
  125.  
  126.         The returned value of the Val function is converted to a string with
  127. Str function.
  128.  
  129. TextSerial.Text
  130. Val(String:"12345678") returns double: 1.23457e+007
  131. Double(1.123457) --> String("12345678")
  132.  
  133.         These lines aren't interesting for the keygen. The crackme gets the
  134. entered serial, converts it to a double, and reconverts it to a string.
  135.        
  136. Len(String:"0") returns LONG:1
  137.  
  138.         The Len function returns the lenght of a string. Here it returns the
  139. lenght of the previous 0 converted to "0", that was returned by the Val
  140. function.
  141.         That's why it returns 0.
  142.  
  143. Str(VARIANT:Double:1.45236e+009)
  144.  
  145.         There we can suppose that the 1 has been transformed to the double
  146. 1.45236e+009, that is here converted to the string "1452356358", which is the
  147. valid serial.
  148.  
  149. String("1452356358") --> Double(1.45236e+009)
  150.  
  151.         Hummm... Smartcheck has shown us lots of step of the routine that
  152. generates the valid serial, but this is not enough, because we don't know
  153. where the final serial come from ! That's why we'll now use SoftIce.
  154.  
  155.  
  156.         The crackme converts another time the string to a double to finally
  157. make a comparison with the serial.
  158.  
  159.         2.b) SoftIce
  160.  
  161.         OK, that's great to use SoftIce, but you surely wonder how we could
  162. do to break exactly in the generation routine. What don't we find an
  163. interesting breakpoint ? To do such a thing, you can use either WinDasm and
  164. select the import in the Functions menu, or a program called Exescope and
  165. the import in the left window. From there we have to find the most interesting
  166. function.
  167.         Hummm... we see :
  168.                 __vbaLenBstr (returns the lenght of a string)
  169.                 rtcR8ValFromBstr (i suppose it's the Val function)
  170.         I propose to choose the __vbaLenBstr function which returns 1 when
  171. the entered name is 'SiFLyiNG'. So make:
  172.         'Bpx __vbaLenBstr' in SoftIce, come back to the crackme and press 'OK'
  173. Boom... you're back in SoftIce and you see in the bottom:
  174.  
  175.         'Break due to Msvbvm50!__vbaLenBstr'
  176.  
  177.         So you press F11 to returns to the caller (in the crackme code) and
  178. you should see:
  179.  
  180. :0040659E Call dword ptr [MSVBVM50!__vbaLenBstr] ; returns 1 in EAX
  181. :004065A4 imul eax, 0000000C                     ; eax=eax*0xC=eax*12=1*12=12
  182. :004065A7 jo 004067F8                            ; jmp if overflow
  183.  
  184.         Yes!!! we are just where we wanted to go :) Let's see what happens
  185. after that :
  186.  
  187. :004065AD mov dword ptr [ebp-0084], eax          ; stores eax=0xC in [ebp-84]
  188. :004065B3 lea ecx, dword ptr [ebp-3C]
  189. :004065B6 fild dword ptr [ebp-0084]
  190.  
  191. NB: there you should see the toggle floating point stack window in Softice. If
  192. it's not the case, just press wf.
  193.  
  194. The fild (integer load) instruction converts a 16,32 or 64 bit two's complement
  195. integer to the 80 bits extended precision format and pushes the result onto
  196. stack. I advise you to read the chapter 14 of the Art Of Assembly available
  197. on the net. It deals with FPU instructions you can meet in some protections.
  198.  
  199. So, what is line has done is to convert the Dword at the address pointed by
  200. [ebp-84] into a Real8 and pushes the result on the FPU. You can see the data
  201. in the toggle floating point stack window :
  202.  
  203.         here we have st0 = 12
  204.  
  205.         Hey ! it's the 12=0xC that we was previously calculated by: 1*0xC
  206.         So we can go on tracing: we're on the good way :)
  207.  
  208. :004065BC lea edx, dword ptr [ebp-4C]
  209. :004065BF push ecx
  210. :004065C0 push edx
  211. :004065C1 mov [ebp-3C], 00000005
  212. :004065C8 fstp Real8 ptr [ebp-8C]
  213.  
  214. * The FSTP instruction copy the value on the top of the floating point
  215. register (st0) to another floating points register or to a 32, 64 or 80
  216. bit memory variable (it's the case here).The FSTP instruction pops the value
  217. off the top of stack when moving it to the destination location. That's the
  218. reason why st0 is empty now.
  219.  
  220. :004065CE fld Real8 ptr [ebp-8C]
  221.  
  222. * The FLD instruction loads a 32 bit, 64 bit, or 80 bit floating point value
  223. (it's the case here) onto the stack.
  224.         So we have here : st0 = 12
  225.  
  226. :004065D4 cmp dword ptr [00407000], 00000000
  227. :004065DB jne 004065E5                  : this jump is not taken
  228. :004065DD fdiv Real8 ptr [00401010]
  229.  
  230. * The fdiv instruction computes the following quotient:
  231.         st0 = st0 / 80 bit floating point value at [401010]
  232.  
  233.         Wtf ??? how do we know this 80 bit value ? Hummm... i have one method,
  234. very intuitive : to divide the previous st0 with the result of the fdiv.
  235.  
  236.         Here, the result is 6. So the value was 12/6=2 !!! This is very
  237. important to keygen !
  238.  
  239. :004065E3 jmp 004065F6
  240.  
  241.         Let's see where we land after the jump :
  242.  
  243. :004065F6 fsub Real8 ptr [00401018]
  244.  
  245. Ok i suppose you understand what this instruction make. Here the result is:
  246.  
  247.         st0 = 1452356358 hey ! it looks like the serial ;)
  248.  
  249.         Let's reverse it in order to see the value of the 80 bit value
  250. stored at [00401018] :
  251.  
  252.         6-X = 1452356358 <=> X = -1452356358+6 = -1452356352
  253.  
  254. Now we have all that is necessary to write a keygen for this crackme. But for
  255. those who are curious and wonder how the entered serial and the valid serial
  256. are compared, just trace a bit until you land here:
  257.  
  258. :00406662 mov eax, dword ptr [ebp-28]  ; eax points to the entered serial
  259.                                        ; in wide characters (1.2.3.4.5.6.7.8.)
  260. :00406665 push eax                     ; push the mem location of the entered
  261.                                        ; serial
  262. :00406666 Call dword ptr [MSVBVM50!__vbaR8Str] ; converts the string stored
  263.                                        ; in the last pushed location (here
  264.                                        ; it was eax) into a 80 bit value
  265. :0040666C fcomp Real8 ptr [ebp-24]
  266.  
  267.         Here [ebp-24] points to the 80 bit value of the valid serial. So this
  268. instruction makes a comparison.
  269.  
  270. * With a 80 bit memory operand, the Fcomp instruction compare the memory
  271. variable against st0, setting the condition code bits accordingly. Fcomp
  272. also pops st0 after the comparison.
  273.  
  274. :0040666F fstsw ax                     ; return ax=4000h if they are equal 
  275. :00406671 test ah, 40                  ; test if equal
  276. :00406674 je 0040667D                  ; jump to "great job" if they are equal
  277. :00406676 mov esi, 00000001
  278. :0040667B jmp 0040667F                 ; otherwise, jump to "Invalid serial" 
  279.  
  280.         Waouhhh !!! it's almost finished :P
  281.         Let's summarize the keygen routine now :
  282.  
  283. 1. Takes the value of the entered string : Val(UserName)
  284. 2. Convert it to a string: Str(Val(Username)
  285.         i advise to add Trim to avoid getting space in front of the string,
  286.         because w could get an error otherwise.
  287.         so Trim(Str(Val(UserName)))
  288. 3. Gets the len of this string: Len(Trim(Str(Val(UserName))))
  289. 4. Multiply it with 12 and divide it with 2
  290.         so it multiplies it with 6:
  291.      Len(Trim(Str(Val(UserName)))) * 6
  292. 5. Finally substract -1452356352 to this value
  293.         so it add 1452356352:
  294.  
  295.         Serial = Len(Trim(Str(Val(UserName)))) * 6 + 1452356352
  296.  
  297. ___________________________________________________________________________
  298.  
  299. The end...
  300.  
  301.         Voila, it's finished: crackme cracked, keygened too :) I've tried
  302. to make this tut as understandable as i could. I hope you've read it entirely
  303. and enjoyed it over all !!! I've writed enough for today so i won't make a big
  304. conclusion. But if you have questions, critics, suggestions, just mail me.
  305.  
  306.                 SiFLyiNG
  307.                         siflying@ifrance.com
  308.  
  309.         Greetz : ACiD BuRN, Magic Raphoun, Lucifer48, Eternal Bliss, AB4DS
  310.                 Volatility, VisionZ, Liquid, Skymarshall, webm4sta, Fireworks
  311.                 and all the authors of crackmes and tutorials
  312.  
  313.  
  314.                   
  315.